<template>
	<div ref="monacoRef" :style="editorStyle"></div>
</template>

<script setup>
import { editor, Range } from 'monaco-editor'
import { ref, computed, onMounted, onUnmounted } from 'vue'

const emit = defineEmits(['update:modelValue', 'setValue', 'insertValue'])
const props = defineProps({
	modelValue: {
		type: String,
		default: `console.log('hello world')`
	},
	language: {
		type: String,
		default: 'javascript'
	},
	theme: {
		type: String,
		default: 'vs-dark'
	},
	readOnly: {
		type: Boolean,
		default: false
	},
	fontSize: {
		type: Number,
		default: 16
	},
	width: {
		type: Number,
		default: null
	},
	height: {
		type: Number,
		default: null
	}
})

const monacoRef = ref(null)
let monacoEditor = null
const editorStyle = computed(() => {
	const style = {
		with: '100%',
		height: '100%'
	}
	if (props.width) style.with = `${props.width}px`
	if (props.height) style.height = `${props.height}px`
	return style
})

// 更改editor内容
const setValue = (val) => {
	monacoEditor.setValue(val)
	// monacoEditor.getAction('editor.action.formatDocument')._run()
}

// 光标位置插值
const insertValue = (insertText) => {
	if (monacoEditor) {
		// 1 获取光标位置
		const position = monacoEditor.getPosition()
		const model = monacoEditor.getModel()
		// 2 插入
		model.applyEdits([
			{
				range: new Range(position.lineNumber,
					position.column,
					position.lineNumber,
					position.column),
				text: insertText,
				forceMoveMarkers: true
			}
		])
		// 3 聚焦
		monacoEditor.focus()
	}
}
const init = () => {
	// 初始化编辑器，确保dom已经渲染，dialog中要写在opened中
	monacoEditor = editor.create(monacoRef.value, {
		value: props.modelValue,
		readOnly: props.readOnly,//是否只读
		language: props.language,
		theme: props.theme,// 主题
		// minimap: { enabled: false }, // 小地图
		// automaticLayout: true, // 自动布局,
		// codeLens: true,
		// colorDecorators: true,
		// contextmenu: false,
		// formatOnPaste: true,
		// overviewRulerBorder: false, // 滚动条的边框
		// scrollBeyondLastLine: true,
		fontSize: props.fontSize, // 字体
	})
	// onDidChangeModelContent，方法产生的监听需要在组件销毁的时候dispose下
	console.log(monacoEditor)
	monacoEditor.onDidChangeModelContent(() => {
		console.log('change')
		try {
			const newValue = monacoEditor.getValue();
			emit('update:modelValue', newValue)
		} catch (err) {
			console.error(err)
		}
	});
}

defineExpose({
	setValue,
	insertValue
})
onMounted(() => {
	init()
})
onUnmounted(() => {
	// 销毁编辑器
	monacoEditor && monacoEditor.dispose()
})
</script>
<style lang='less' scoped></style>
